package com.zrf.testchatgpt.shiro.util;

import com.zrf.testchatgpt.constant.Constant;
import io.jsonwebtoken.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.xml.bind.DatatypeConverter;
import java.util.Date;

import java.util.Map;

@Slf4j
@Component
@Data
@ConfigurationProperties(prefix = "jwt")
public class JwtTokenUtil {
    //token的秘钥
//    @Value("${jwt.securityKey}")
    private  String securityKey;
//    @Value("${jwt.accessTokenExpireTime}")
    private  Long accessTokenExpireTime;
//    @Value("${refreshTokenExpireTime}")
    private  Long refreshTokenExpireTime;
//    @Value("${refreshTokenExpireAppTime}")
    private  Long refreshTokenExpireAppTime;
//    @Value("${issuer}")
    private  String issuer;

    /**
     * 签发token
     */
    public  String generateToken(String issuer, String subject, Map<String, Object> claims, long ttlMillis, String secret) {
        JwtBuilder builder = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(subject)
                .setIssuer(issuer)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS256,  DatatypeConverter.parseBase64Binary(secret));
        if (ttlMillis >= 0) {
            //过期时间=当前时间+过期时长
            long nowMillis = System.currentTimeMillis();
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 生成 access_token：这个过期时间比较短，token的过期时间是2小时
     */
    public  String getAccessToken(String subject, Map<String, Object> claims) {
        return generateToken(issuer, subject, claims, accessTokenExpireTime, securityKey);
    }

    /**
     * 生成 PC refresh_token：这个过期时间比较长，是8小时
     */
    public  String getRefreshToken(String subject, Map<String, Object> claims) {
        return generateToken(issuer, subject, claims, refreshTokenExpireTime, securityKey);
    }

    /**
     * 解析token：从token中获取claims
     */
    public  Claims getClaimsFromToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(securityKey))
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            if (e instanceof ClaimJwtException) {
                claims = ((ClaimJwtException) e).getClaims();
            }
        }
        return claims;
    }

    /**
     * 获取用户id
     */
    public  String getUserId(String token) {
        String userId = null;
        try {
            Claims claims = getClaimsFromToken(token);
            userId = claims.getSubject();
        } catch (Exception e) {
            log.error("eror={}", e);
        }
        return userId;
    }

    /**
     * 获取用户名
     */
    public  String getUserName(String token) {
        String username = null;
        try {
            Claims claims = getClaimsFromToken(token);
            username = (String) claims.get(Constant.JWT_TOKEN_USERNAME);
        } catch (NullPointerException e) {
            log.error("eror={}", e);
        }
        return username;
    }
    public Object getInfoByKey(String token,String key){
        String result=null;
        try {
            Claims claims = getClaimsFromToken(token);
            result = (String) claims.get(key);
        } catch (Exception e) {
            log.error("eror={}", e);
        }
        return result;
    }
    /**
     * 验证token 是否过期(true:已过期 false:未过期)
     */
    public  Boolean isTokenExpired(String token) {
        try {
            Claims claims = getClaimsFromToken(token);
            //token的过期时间 = 签发token时的时间 + 过期时长
            Date expiration = claims.getExpiration();

            return expiration.before(new Date());
        } catch (Exception e) {
            log.error("error={}", e);
            return true;
        }
    }

    /**
     * 验证token是否有效 (true：验证通过 false：验证失败)
     */
    public  Boolean validateToken(String token) {
        Claims claimsFromToken = getClaimsFromToken(token);
        return (claimsFromToken != null && !isTokenExpired(token));
    }

    /**
     * 获取token的剩余过期时间
     */
    public  long getRemainingTime(String token) {
        long result = 0;
        try {
            long nowMillis = System.currentTimeMillis();
            //剩余过期时间 = token的过期时间-当前时间
            result = getClaimsFromToken(token).getExpiration().getTime() - nowMillis;
        } catch (Exception e) {
            log.error("error={}", e);
        }
        return result;
    }
//    @Autowired
//    static JwtTokenUtil jwtTokenUtil;
//    public static void main(String[] args) {
//////        Map<String,Object> map=new HashMap<>();
//////        map.put("wxName","zrf");
//////        map.put("openai","openid");
//////        map.put(Constant.ROLES_INFOS_KEY,"admin");
//////        map.put(Constant.PERMISSIONS_INFOS_KEY,"select");
////        JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
//////        String accessToken = jwtTokenUtil.getAccessToken("admin", map);
//////        System.out.println(accessToken);
//        System.out.println(jwtTokenUtil.getAccessTokenExpireTime());
////        System.out.println(jwtTokenUtil.refreshTokenExpireTime);
////        System.out.println(jwtTokenUtil.securityKey);
////        System.out.println(jwtTokenUtil.issuer);
//    }
}
